home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-07-15 | 30.9 KB | 976 lines | [TEXT/MPS ] |
- { © Copyright 1989,90,91 The NetWork Project, StatLab Heidelberg.
- © Copyright 1989,90,91 Joachim Lindenberg, Karlsruhe,
- Günther Sawitzki, Heidelberg. All rights reserved. }
-
- { This library does not support code without an A5 world. If you want to use
- NetWork from other code (non application, non tool), you´ll have to use
- control calls to the driver directly. Contact us if you need help with that.
-
- The library uses a call to NetWork Processor to find out whether this process
- is already known to NetWork. If it is, it is assumed to be launched by NetWork
- by means of a message or idle time launch, and the type and signature are confirmed.
- If it is not known, the process is registered using the default type and the
- application´s signature. The default type is pMaster unless you set pDefault to
- something different. It is allowed to use pSlave or pLocal even if not launched
- automatically, and the process will be subject to the rules of slave/local
- processes in that case.
- }
-
- {$IFC UNDEFINED UsingIncludes}
- {$SETC UsingIncludes:=false}
- {$ENDC}
-
- unit NetWork;
-
- interface
-
- { a star indicates that NetWork depends on these units, other comments indicate which unit
- requires the inclusion of this unit. Tripple stars mark the units that are required
- by the interface part of NetWork. If you use NetWork, but don´t use these units prior
- to NetWork, NetWork will automatically include them. Note that conscious use of uses
- will speed your compiles considerably. }
-
- uses Types {***}, FixMath {Packages}, QuickDraw {***lots of other units***},
- Events {*}, OSUtils {***}, SegLoad {Files}, Files {Devices, StandardFile/Packages}, Devices {*},
- Errors {*}, Memory {*}, Resources {*},
- Packages {*}, SysEqu {*}, Traps {*},
- ToolUtils {NetWorkLookup}, AppleTalk {NetWorkLookup};
-
- {$I+}
- {$SETC NetWorkIncludes:=UsingIncludes}
- {$SETC UsingIncludes:=true}
- {$SETC UsingNetWork:=true}
- {$SETC UsingNetWorkUtilities:=true}
-
- {$IFC UNDEFINED UsingTypes}
- {$I $$SHELL(PInterfaces)Types.p}
- {$ENDC}
-
- {$IFC UNDEFINED UsingOSUtils}
- {$I $$SHELL(PInterfaces)OSUtils.p}
- {$ENDC}
-
- {$SETC UsingIncludes:=NetWorkIncludes}
-
-
- { ============================================================= }
-
- { global declarations - general use }
-
- const
-
- { general error messages - many of them are never returned to user processes.
- Also other operating system error codes may bubble up. }
-
- { some of these codes should be reconsidered, also some of them could be more specific }
-
- eQueEmpty = -31000; { no more messages avail - out of memory }
- { eMsg2Big = ? { message (priority + standard) too big }
- ePrio2Big = -31001; { priority information too big }
- { eCore2Big = ? { core information too big }
- eNoSuchMsg = -31002; { invalid or NIL message reference, no message avail (GET) }
- eNotLaunched = -31003; { destination process does not exist - NOT USED }
- eAbortMsg = -31004; { message transfer aborted }
- eProcTableFull = -31005; { process table full (Init/Exit) }
- eNoSuchProcess = -31006; { specified process unknown }
- eNoMoreDynamics = -31007; { maximum number of dynamic ids exceeded }
- eLaunchFailed = -31008; { launch failed - NOT USED }
- eInvalid = -31009; { local message transfer aborted }
- eSizeLimit = -31010; { message larger than supported by transport - AppleTalk broadcast - eMsg2Big }
- eVersion = -31011; { version of library/driver/transport/system }
- eProtType = -31012; { no transport, invalid network address - Dispatcher }
- eLoopback = -31013; { discard of broadcasted message - NEVER returned to user }
- eTransportDown = -31014; { transport system not available - AppleTalk }
- eCmdSequence = -31015; { cmd sequencing error - bug of NetWork Processor or Dispatcher }
- eProtIndex = -31016; { protocol index out of range - GetTransport }
- eProcessExists = -31017; { creator registered for a DIFFERENT process - process mgmt }
- eProcessIndex = -31018; { invalid process index - GetIndexedProcess }
- eProcessType = -31019; { process type illegal or does not match launch - process mgmt }
- eRestartListen = -31020; { a listener handled a request for more data,
- and requires a restart therefore - AppleTalk - NEVER returned to user }
- eMsgTimeout = -31021; { maximum message lifetime exceeded - AppleTalk }
- eNoSignature = -31022; { couldn´t obtain signature of application file - Library }
- eMsgLockFailed = -31023; { couldn´t lock message - NOT USED }
- eSigTableFull = -31024; { signature table full }
- eSigRegistered = -31025; { signature already registered }
- eSigNotRegistered = -31026; { signature not registered }
- eProcMgmtError = -31027; { internal error }
- eSourceSig = -31028; { source signature wrong in Send/Post }
- eSourceAddr = -31029; { source address wrong in Send/Post }
-
- { capas defined }
-
- cMustExist = $80000000; { process must exist -- don´t launch }
-
- { idle monitor states - see NetWork TN 12 Idle Monitor States }
-
- imBusy = 0;
- imIdle = 1;
- imActive = 2;
- imLoaded = 3;
-
- { process types - see NetWork Communications }
-
- pUnknown = 0;
- pSlave = 1;
- pLocal = 2;
- pMaster = 3;
-
- { transport system constants }
-
- { major command codes }
-
- tGeneral = $00;
- tListen = $10;
- tGet = $20;
- tAccept = $30;
- tSend = $40;
- tPost = tSend; { alias for compatibility }
-
- { minor command codes }
-
- tStart = $00;
- tTimeout = $0C;
- tTimeout1 = $0D;
- tAbort = $0E;
- tAbort1 = $0F;
-
- { misc command codes }
-
- tInit = $00;
- tTickle = $01;
- tDeRegister = $02;
- tRegister = $03;
- tShutdown = $0F;
-
- { useful values }
-
- tMajorMask = $F0;
- tMinorMask = $0F;
-
- type
-
- MsgAddr = record
- a : longint; { network address - depends on transport prot }
- p : longint; { signature or program number - use longint ('APPL') }
- end;
-
- MsgPtr = ^MsgRec;
- TransportPtr = ^TransportRecord;
-
- { except for MsgUserRefCon all of the components are READ ONLY }
-
- MsgRec = record
-
- MsgLink : MsgPtr; { NetWork Processor internal use }
- Msg2ndLink : Ptr; { NetWork Processor internal use }
-
- MsgResult : integer; { >0 busy, =0 done, <0 error }
- MsgFlags : SignedByte; { reserved - lock & attn flags }
- MsgCmd : SignedByte; { command (phase), see documentation }
- MsgTicks : longint; { time (in ticks) this message will become invalid }
-
- MsgUserRefCon : longint; { reserved for NetWork Scheduler }
- MsgReserved1 : longint; { future NetWork Processor internal use }
- MsgReserved2 : longint; { future NetWork Processor internal use }
- MsgReserved3 : longint; { future NetWork Processor internal use }
-
- MsgTrpPtr : TransportPtr; { transport system used by message }
- MsgTrpRefCon : longint; { free for transport system use }
-
- { message header information - all of this is transported to the destination }
-
- MsgSource : MsgAddr; { not guaranteed, use reply address }
- MsgDest : MsgAddr;
- MsgReply : MsgAddr;
- MsgCapasVerb : longint;
- MsgReference : longint;
- MsgPrioSize : longint;
- MsgCoreSize : longint;
- MsgPrioPtr : Ptr; { pointer to data structure allocated by application }
- MsgCorePtr : Ptr; { pointer to data structure allocated by application }
-
- end;
-
- { transport system }
-
- TransportRecord = record
- TransportLink : TransportPtr; { link to next transport in queue }
- TransportProc : Ptr; { pointer to definition proc - overlays magic }
- TransportName : StringHandle; { name of resource - overlays header version & size }
- TransportID : longint; { transport protocol (unique) signature }
- TransportDomain : StringHandle; { transport domain identifier, may be NIL }
- TransportAddr : longint; { local address of this transport system }
- TransportBCAddr : longint; { this transports broadcast address }
- TransportStart : longint; { first valid address }
- TransportEnd : longint; { last valid address }
- TransportMsgSize : integer; { size of MsgRecord for this transport system }
- TransportListensRequested, { see NetWork Transports for a discussion }
- TransportListensStarted, { of these three fields. }
- TransportListensCompleted : integer;
- TransportReserved : longint; { reserved for future use }
- TransportVars : Ptr; { private vars, may be longint, ptr, or handle }
- TransportMsgQHead : ^MsgPtr; { pointer to head of queue (supplied by NetWork) }
- TransportAttnRtn : Ptr; { pointer to attn routine (supplied by NetWork) }
- end;
-
-
- { ============================================================= }
-
- { conversion & logging }
-
- procedure AddrToString (Addr: MsgAddr; var s: Str255);
- procedure MsgToString (Msg: MsgPtr; var s: Str255);
- procedure LogString (s : str255);
- procedure LogStrTime (s : str255);
- procedure LogMsg (Why : Str255; Msg : MsgPtr);
- procedure CheckError (s : str255; e : OSErr); { logs error if e <> 0 -- bad practice - to go }
- function Logging : boolean;
- procedure SetLogging (on : boolean);
-
- { ============================================================= }
-
- { general utilities }
-
- procedure ProgramBreak (s : Str63); { drop into debugger if one is installed -- SADE ? (new calls) -- to go? }
- function Visible : boolean; { display a user interface ? }
- function Spare : boolean; { this returns the setting of the spare flag }
- function TimeStamp : longint; { randomized timestamp, should be unique for each call -- (sample code) }
-
- { ============================================================= }
-
- { idle manager }
-
- procedure PreventIdle; { tell NetWork that we are doing useful stuff - to go ? }
- function IdleMonitorState : integer; { state of idle monitor }
- function Idle : boolean; { is the local system idle ? }
- function IdleTicks : longint; { number of ticks we have been idle, < 0 if busy }
-
- { ============================================================= }
-
- { transport interface }
-
- function IsLocal (a : longint) : boolean; { shouldn´t be used. to go ? }
- function GetTransport (var TrpPtr : TransportPtr; index : integer) : OSErr; { to go ? }
- function GetTransportQHdr : QHdrPtr;
- function InstallTransport (Trp : TransportPtr) : OSErr;
- function RemoveTransport (Trp : TransportPtr) : OSErr;
-
- { ============================================================= }
-
- { address management - to go ? }
-
- function EqAddr (a, b : MsgAddr) : boolean;
- function EqNode (a, b : MsgAddr) : boolean;
- function SetMsgAddr (a, p : longint) : MsgAddr;
- function GetNetWorkAddr : MsgAddr;
-
- { ============================================================= }
-
- { process management }
- { most of the process management is done implicitly, these may
- be the things you are interested in. }
-
- var
- pFileSignature : longint; { valid after InitNetWork }
- pProcessSignature : longint;{ valid after InitNetWork }
-
- function Master : boolean; { manually launched ? }
-
- function GetProcessType (signature : longint; var ptyp : integer) : OSErr;
- function SetProcessType (signature : longint; ptyp : integer) : OSErr;
- function GetIndProcess (var signature : longint; index : integer) : OSErr;
-
- function LaunchLocalApplication (var signature : longint;
- WDRef : integer; DirID : longint; AppName : Str255) : OSErr;
-
- { ============================================================= }
-
- { message management }
-
- { DumpMessages dumps all currently active messages - is this useful to applications ? }
-
- procedure DumpMessages;
-
- { AvailableMsg returns the number of available messages - to go }
-
- function AvailableMsg : integer;
-
- { the following procedure returns 0 if the Msg has been transferred completely
- < 0 if there was an error, > 0 indicates that the Msg is still transferred
- or waiting. }
-
- function MsgStatus (Msg : MsgPtr) : OSErr; { to go ? }
-
- { SignalMsg checks to see if a new or old message needs handling }
-
- function SignalMsg (var Msg : MsgPtr) : OSErr; { useful for non app code }
-
- { GetMsg checks to see if there is a new message available. }
-
- function GetIndexedMsg (var Msg : MsgPtr;
- Index : integer; {0=1}
- PrioData : UNIV Ptr;
- MaxPrioSize : longint) : OSErr;
-
- { GetMsg gets a message that has been signaled }
-
- function GetMsg (Msg : MsgPtr;
- PrioData : UNIV Ptr;
- MaxPrioSize : longint) : OSErr;
-
- { FlushMsg discards all received messages not "Got" except those with DontFlushMask set }
-
- function FlushMsg (DontFlushMask : longint) : OsErr;
-
- { AcceptMsg will tell the transport system to receive the message and store
- it at the memory passed. }
-
- function AcceptMsg (Msg : MsgPtr;
- CoreData : UNIV Ptr; MaxCoreSize : longint) : OSErr;
-
- { PostMsg generates a new message that will be sent. It does not make a copy
- of the information that is referenced. }
-
- function PostMsg (var Msg : MsgPtr; Trp : TransportPtr;
- Capas, Stamp : longint; DestAddr, ReplyAddr : MsgAddr;
- PrioData : UNIV Ptr; PrioSize : longint;
- CoreData : UNIV Ptr; CoreSize : longint) : OSErr;
-
- { SendMsg uses the information in RefMsg to post a new message. All of the
- fields must be filled in. The message posted is returned in NewMsg. }
-
- function SendMsg (RefMsg : MsgPtr; var NewMsg : MsgPtr) : OSErr;
-
-
- { ForwardMsg forwards a message to the same or another process on the same machine.
- Don´t call DestroyMsg for a message you forwarded except if you forward to yourself.
- ForwardMsg may be called after a GetMsg, but all buffer references will be removed }
-
- function ForwardMsg (Msg : MsgPtr; ForwardTo : longint) : OSErr;
-
- { DestroyMsg gets rid of a message. This possibly kills a transfer }
-
- function DestroyMsg (Msg : MsgPtr) : OSErr;
-
- { ============================================================= }
-
- { Initialization. Call InitNetWork before use of any procedure funtion
- within this unit or they won´t work. If you want to use events, then
- pass a event number for use (e.g. NetWorkEvt), else pass 0. }
-
- function InitNetWork (eventno : integer) : OSErr;
-
- { this function is obsolete and should no longer be used.
- function ExitNetWork : OSErr;
- }
-
- implementation
-
-
- { Copyright 1989,1990,1991 Joachim Lindenberg, Karlsruhe. All rights reserved. }
-
- { this file contains the interface used by driver and library to
- comunicate with each other. This is included, not used }
-
- const
-
- LibRelease = '12b0'; { validity check of interface to driver,
- changed whenever the calls or records change }
-
- { driver cscodes }
-
- { message commands }
-
- csGetMsg = 200; { get nth message received }
- csSignalMsg = 201; { returns message with ioresult <= 0 }
- csSendMsg = 202; { clone & send a message }
-
- csForwardMsg = 206; { forward a message }
- csGetThisMsg = 207; { get a specific message }
- csAcceptMsg = 208; { accept a message got }
- csDestroyMsg = 209; { destroy a message }
-
- csMsgCount = 195; { count available messages }
- csFlush = 196; { flush all received messages not yet got }
- csDumpMsgs = 197; { dump all currently active messages }
- csSigEvent = 199; { use eventnumber to signal events }
-
- { transport commands }
-
- csGetTrpQHdr = 190; { get transport queue header }
- csInstallTrp = 191; { install new transport system }
- csRemoveTrp = 192; { remove transport system }
- csIsLocal = 194; { test if address is local }
-
- { process commands }
-
- csMsgInit = 180; { register a signature }
- csMsgExit = 181; { deregister a signature }
- csGetPInfo = 182; { get process type }
- csSetPInfo = 183; { set process type }
- csGetIProc = 184; { get indexed process signature }
- csProcKnown = 185; { returns type and signature if the active process is known
- to NetWork, otherwise error }
- csLaunchTool = 186; { launch program }
- csKilling = 189; { is killing possible ? }
-
- { logger commands }
-
- csMsg2Str = 170; { convert a message to a string }
- csAddr2Str = 171; { convert an address to a string }
- csLoggErr = 172; { logs a string to the logfile }
- csLoggTime = 173; { cLoggErr, but with time }
- csLogMsg = 174; { log message --- was 205 }
- csErr2Str = 175; { convert an error number to a message string }
- csLogControl = 179; { control log file mode }
-
- { idle commands }
-
- csGetIdleTicks = 160; { ticks since idle }
-
- { misc commands }
-
- csGetBGOnly = 161; { returns visible setting }
- csGetSpare = 162; { returns spare setting }
- csCheckVers = 163; { version negotiation }
- csIgnored = 164; { this command specifically ignored (used internally) }
-
- { cdev commands - for cdev use only }
-
- csCdevChange = 165; { settings changed - internal use of cdev only }
- csCheckPath = 166; { test if path exists }
-
- { statistics - reserved - do not use because these may change with every release }
-
- csIdleStats = 169; { get idle monitor statistics }
- csMsgStats = 168; { get message statistics }
-
- type
-
- { this parameter block is used by the driver interface }
-
- MsgControlPtr = ^MsgControlBlock;
- MsgControlBlock = record
-
- { standard device manager header }
-
- qLink: QElemPtr;
- qType: INTEGER;
- ioTrap: INTEGER;
- ioCmdAddr: Ptr;
- ioCompletion: ProcPtr;
- ioResult: OSErr;
- ioNamePtr: StringPtr;
- ioVRefNum: INTEGER;
- ioRefNum: INTEGER;
- csCode : integer;
-
- { driver specific information }
-
- ioSignature: longint;
- ioMessage: MsgPtr;
- ioIndex : integer; { GetMsg, Get/SetProcessInfo }
- ioBuffer : Ptr; { used to pass prio/core buffer }
- ioSize : longint; { space to GetMsg/AcceptMsg }
- end;
-
- type CharPtr = ^CharArray; CharArray = packed array [0..1] of char;
-
- {$D+} { full Macsbug symbols }
-
- { ============================================================= }
-
- function EqNode (a, b : MsgAddr) : boolean;
- begin
- EqNode := (a.a = b.a) | (IsLocal (a.a) & IsLocal (b.a));
- end;
-
- function EqAddr (a, b : MsgAddr) : boolean;
- begin
- EqAddr := (a.p = b.p) & EqNode (a, b);
- end;
-
- { ============================================================= }
-
- { private variables }
-
- var
- gError : OSErr;
- gMiscID : longint;
- gControl : MsgControlBlock; { global parameter block }
-
- { general utilities }
-
- procedure ProgramBreak (s : str63);
- type longptr = ^longint;
- begin
- if (longptr ($120)^ <> 0) {| (NGetTrapAddress (_DebugStr, ToolTrap) <> NGetTrapAddress (_Unimplemented, ToolTrap))} then
- DebugStr (s);
- end;
-
- procedure PreventIdle;
- var l : longint; e : integer;
- begin
- l := 1; e := FSWrite (gControl.ioRefNum, l, Nil); { don´t report error if old driver }
- end;
-
- procedure AddrToString (Addr: MsgAddr; var s: Str255);
- begin
- s := ''; { Driver appends -- remove this line if you want to pass a prefix string }
- gControl.csCode := csAddr2Str;
- gControl.ioBuffer := @s; gControl.ioMessage := @Addr;
- gError := PBControl (@gControl, false);
- end;
-
- procedure MsgToString (Msg: MsgPtr; var s: Str255);
- begin
- s := ''; { Driver appends -- remove this line if you want to pass a prefix string }
- gControl.csCode := csMsg2Str;
- gControl.ioBuffer := @s; gControl.ioMessage := Msg;
- gError := PBControl (@gControl, false);
- end;
-
- procedure LogString (s : str255);
- begin
- gControl.csCode := csLoggErr;
- gControl.ioBuffer := @s;
- gError := PBControl (@gControl, false);
- end;
-
- procedure LogStrTime (s : str255);
- begin
- gControl.csCode := csLoggTime;
- gControl.ioBuffer := @s;
- gError := PBControl (@gControl, false);
- end;
-
- procedure LogMsg (Why : Str255; Msg : MsgPtr);
- begin
- gControl.csCode := csLogMsg;
- gControl.ioBuffer := @why;
- gControl.ioMessage := Msg;
- gError := PBControl (@gControl, false);
- end;
-
- procedure CheckError (s : str255; e : integer);
- var t : str255;
- begin
- if e = 0 then exit (CheckError);
- NumToString (e, t); LogString (concat (s, ' Error # ', t));
- end;
-
- function Logging : boolean;
- begin
- gControl.csCode := csLogControl;
- gControl.ioIndex := -1;
- Logging := (PBControl (@gControl, false) = noErr) & (gControl.ioIndex > 0);
- end;
-
- procedure SetLogging (on : boolean);
- begin
- gControl.csCode := csLogControl;
- if on then gControl.ioIndex := maxint else gControl.ioIndex := 0;
- gError := PBControl (@gControl, false);
- end;
-
- function TimeStamp : longint;
- var p, q : Point; l, k : longint;
- begin
- GetDateTime (longint (p));
- q.h := p.v; q.v := p.h; l := longint (q); k := TickCount;
- l := BOr (l, k) - BAnd (l, k); { XOR }
- if l = 0 then l := -1; { 0 reserved, though this is very unlikely }
- TimeStamp := l;
- end;
-
- function IsLocal (a : longint) : boolean;
- begin
- longint (gControl.ioMessage) := a; gControl.csCode := csIsLocal;
- IsLocal := PBControl (@gControl, false) = noErr
- end;
-
- { transport interface }
-
- function GetTransportQHdr : QHdrPtr;
- begin
- with gControl do begin
- csCode := csGetTrpQHdr;
- if PBControl (@gControl, false) = noErr then GetTransportQHdr := QHdrPtr (ioMessage)
- else GetTransportQHdr := nil;
- end;
- end;
-
- function InstallTransport (Trp : TransportPtr) : OSErr;
- begin
- with gControl do begin
- csCode := csInstallTrp; TransportPtr (ioMessage) := Trp;
- InstallTransport := PBControl (@gControl, false);
- end;
- end;
-
- function RemoveTransport (Trp : TransportPtr) : OSErr;
- begin
- with gControl do begin
- csCode := csRemoveTrp; TransportPtr (ioMessage) := Trp;
- RemoveTransport := PBControl (@gControl, false);
- end;
- end;
-
- function GetTransport (var TrpPtr : TransportPtr; index : integer) : OSErr;
- var q : QHdrPtr; p : TransportPtr;
- begin
- q := GetTransportQHdr; p := nil;
- if q <> nil then begin { …else no NetWork Processor }
- p := TransportPtr (q^.qHead);
- while (index > 0) & (p <> nil) do begin index := index - 1; p := p^.TransportLink end;
- end;
- TrpPtr := p;
- if p <> nil then GetTransport := noErr else GetTransport := qErr;
- end;
-
- function SetMsgAddr (a, p : longint) : MsgAddr;
- var m : MsgAddr;
- begin
- m.a := a; m.p := p;
- SetMsgAddr := m;
- end;
-
- function GetNetWorkAddr : MsgAddr;
- var m : MsgAddr;
- begin
- m.a := 0; m.p := gControl.ioSignature;
- GetNetWorkAddr := m;
- end;
-
- { process mangement
- most of the process management is done implicitly, these may
- be the two things you are interested in. }
-
- { visible looks at the background only bit of the current app and at the
- setting of the control panel. }
-
- function Visible : Boolean;
- type IntPtr = ^Integer; IntHandle = ^IntPtr;
- var sizehandle : IntHandle; vis : boolean;
- begin
- sizehandle := IntHandle (GetResource ('SIZE', 0));
- if sizehandle = nil then sizehandle := IntHandle (GetResource ('SIZE', -1));
- if sizehandle <> nil then
- if BAnd (sizehandle ^^, $0400) <> 0 then vis := false { faceless background task }
- else with gControl do begin { not faceless, get control panel setting }
- csCode := csGetBGOnly;
- vis := PBControl (@gControl, false) <> noErr;
- end;
- Visible := vis
- end;
-
- function Idle : Boolean;
- begin
- Idle := IdleMonitorState > imBusy;
- end;
-
- function GetProcessType (signature : longint; var ptyp : integer) : OSErr;
- var lcontrol : MsgControlBlock;
- begin
- lcontrol := gControl; lcontrol.csCode := csGetPInfo;
- if signature <> 0 then lcontrol.iosignature := signature;
- GetProcessType := PBControl (@lControl, false);
- ptyp := lcontrol.ioindex;
- end;
-
- function SetProcessType (signature : longint; ptyp : integer) : OSErr;
- var lcontrol : MsgControlBlock;
- begin
- lcontrol := gControl; lcontrol.csCode := csSetPInfo;
- if signature <> 0 then lcontrol.iosignature := signature;
- lcontrol.ioindex := ptyp;
- SetProcessType := PBControl (@lControl, false);
- end;
-
- function UseEventNo (eventcode : integer) : OSErr;
- begin
- gControl.csCode := csSigEvent; gControl.ioIndex := eventcode;
- UseEventNo := PBControl (@gControl, false);
- end;
-
- function GetIndProcess (var signature : longint; index : integer) : OSErr;
- var lcontrol : MsgControlBlock;
- begin
- lcontrol.csCode := csGetIProc; lcontrol.ioRefNum := gControl.ioRefNum;
- lcontrol.ioindex := index;
- GetIndProcess := PBControl (@lControl, false);
- signature := lcontrol.iosignature;
- end;
-
- function Master : Boolean;
- begin
- gControl.csCode := csGetPInfo; Master := true; { in case no driver ! }
- if PBControl (@gControl, false) = noErr then
- Master := BAnd (gControl.ioIndex, 3) >= pMaster;
- end;
-
- function Spare : boolean; { this returns the setting of the spare flag }
- begin
- gControl.csCode := csGetSpare; Spare := true; { in case no driver ! }
- Spare := PBControl (@gControl, false) = noErr;
- end;
-
- function IdleTicks : longint; { number of ticks we have been idle }
- begin
- gControl.csCode := csGetIdleTicks;
- if PBControl (@gControl, false) = noErr then IdleTicks := longint (gControl.ioBuffer)
- else IdleTicks := -1;
- end;
-
- function IdleMonitorState : integer; { state of idle monitor }
- begin
- gControl.csCode := csGetIdleTicks;
- if PBControl (@gControl, false) = noErr then IdleMonitorState := gControl.ioIndex
- else IdleMonitorState := imBusy;
- end;
-
- { ============================================================= }
-
- { message handling functions }
-
- procedure DumpMessages;
- begin
- with gControl do begin
- csCode := csDumpMsgs;
- if PBControl (@gControl, false) = noErr then;
- end;
- end;
-
- { return the number of available messages}
-
- function AvailableMsg:integer;
- begin
- with gControl do begin
- ioIndex := 0; csCode := csMsgCount;
- if PBControl (@gControl, false) = noErr then AvailableMsg := ioIndex
- else AvailableMsg := 0;
- end;
- end;
-
- { the following procedure returns 0 if the Msg has been transferred completely
- < 0 if there was an error, > 0 indicates that the Msg is still transferred
- or waiting. }
-
- function MsgStatus (Msg : MsgPtr) : integer;
- var err : integer;
- begin
- if Msg <> nil then err := Msg^.MsgResult
- else err := eNoSuchMsg;
- MsgStatus := err;
- end;
-
- { SignalMsg checks to see if a new or old message needs handling }
-
- function SignalMsg (var Msg : MsgPtr) : OSErr;
- begin
- with gControl do begin
- ioMessage := nil; csCode := csSignalMsg;
- SignalMsg := PBControl (@gControl, false);
- Msg := ioMessage;
- end;
- end;
-
- { GetThisMsg gets a message that has been signaled }
-
- function GetMsg (Msg : MsgPtr;
- PrioData : UNIV Ptr;
- MaxPrioSize : longint) : OSErr;
- begin
- with gControl do begin
- ioBuffer := PrioData; ioSize := MaxPrioSize; ioMessage := Msg;
- csCode := csGetThisMsg;
- GetMsg := PBControl (@gControl, false);
- end;
- end;
-
- { GetMsg checks to see if there is a new message available }
-
- function GetIndexedMsg (var Msg : MsgPtr;
- Index : integer;
- PrioData : UNIV Ptr;
- MaxPrioSize : longint) : OSErr;
- begin
- with gControl do begin
- ioBuffer := PrioData; ioSize := MaxPrioSize; ioMessage := nil;
- ioIndex := Index; csCode := csGetMsg;
- GetIndexedMsg := PBControl (@gControl, false);
- Msg := ioMessage;
- end;
- end;
-
- { FlushMsg discards all received messages not "Got" or "Accepted". }
-
- function FlushMsg (DontFlushMask : longint) : OsErr;
- begin
- with gControl do begin
- csCode := csFlush; longint (ioMessage) := DontFlushMask;
- FlushMsg := PBControl (@gControl, false);
- end;
- end;
-
- { AcceptMsg will tell the transport system to receive the message and store
- it at the memory passed. }
-
- function AcceptMsg (Msg : MsgPtr;
- CoreData : UNIV Ptr; MaxCoreSize : longint) : OSErr;
-
- begin
- if Msg <> nil then with gControl do begin
- ioMessage := Msg; csCode := csAcceptMsg;
- ioBuffer := CoreData; ioSize := MaxCoreSize;
- AcceptMsg := PBControl (@gControl, false);
- end
- else begin
- AcceptMsg := eNoSuchMsg;
- CheckError ('AcceptMsg NIL reference', eNoSuchMsg)
- end;
- end;
-
- { SendMsg uses the information in RefMsg to post a new message. All of the
- fields must be filled in. The message posted is returned in NewMsg. }
-
- function SendMsg (RefMsg : MsgPtr; var NewMsg : MsgPtr) : OSErr;
- var TempMsg : MsgRec;
- begin
- with gControl do begin
- csCode := csSendMsg; ioMessage := RefMsg; gError := PBControl (@gControl, false);
- NewMsg := ioMessage;
- end;
- SendMsg := gError;
- end;
-
- { PostMsg generates a new message that will be sent. It does not make a copy
- of the information that is referenced. }
-
- function PostMsg (var Msg : MsgPtr; Trp : TransportPtr;
- Capas, Stamp : longint; DestAddr, ReplyAddr : MsgAddr;
- PrioData : UNIV Ptr; PrioSize : longint;
- CoreData : UNIV Ptr; CoreSize : longint) : OSErr;
- var TempMsg : MsgRec; p : CharPtr;
- begin
- p := @TempMsg; FillChar (p^, sizeof (TempMsg), chr (0));
- with TempMsg do begin
- { MsgUserRefCon := 0; }
- MsgSource.p := gControl.ioSignature;
- if Trp <> nil then MsgSource.a := Trp^.TransportAddr
- { else MsgSource.a := 0 } ;
- MsgTrpPtr := Trp;
- MsgDest := DestAddr; MsgReply := ReplyAddr;
- MsgCapasVerb := Capas; MsgReference := Stamp;
- MsgPrioPtr := PrioData; MsgPrioSize := PrioSize;
- MsgCorePtr := CoreData; MsgCoreSize := CoreSize;
- end;
- PostMsg := SendMsg (@TempMsg, Msg);
- end;
-
- { ForwardMsg forwards a message to the same or another process on the same machine.
- Don´t call DestroyMsg for a message you forwarded except if you forward to yourself.
- ForwardMsg may be called after a GetMsg, but all buffer references will be removed }
-
- function ForwardMsg (Msg : MsgPtr; ForwardTo : longint) : OSErr;
- begin
- with gControl do begin
- csCode := csForwardMsg; ioMessage := Msg; longint (ioBuffer) := ForwardTo;
- gError := PBControl (@gControl, false);
- end;
- ForwardMsg := gError;
- end;
-
- function LaunchLocalApplication (var signature : longint;
- WDRef : integer; DirID : longint; AppName : Str255) : OSErr;
- begin
- with gControl do begin
- ioVRefNum := WDRef; longint (ioBuffer) := DirID; ioNamePtr := @AppName;
- longint (ioMessage) := signature; csCode := csLaunchTool;
- gError := PBControl (@gControl, false); signature := longint (ioMessage);
- end;
- LaunchLocalApplication := gError;
- end;
-
- { DestroyMsg gets rid of a message. This possibly kills a transfer }
-
- function DestroyMsg (Msg : MsgPtr) : OSErr;
-
- begin
- if Msg <> nil then with gControl do begin
- ioMessage := MsgPtr (Msg); csCode := csDestroyMsg;
- gError := PBControl (@gControl, false);
- end
- else begin
- DestroyMsg := eNoSuchMsg;
- CheckError ('DestroyMsg NIL reference', eNoSuchMsg)
- end;
- end;
-
- function InitNetWork (eventno : integer) : OSErr;
- type CharPtr = ^CharArray; CharArray = packed array [0..1] of char;
- var pb : record case boolean of true : (hpb : HParamBlockRec); false : (fpb : FCBPBRec) end;
- appname : Str255; h : Handle; signature : longint;
- ptyp : integer;
- begin
- if gMiscID <> 0 then ProgramBreak ('NetWork Library: Did you compile this unit with -u?');
- GetAppParms (appname, pb.fpb.iorefnum, h); { in case we need to log an error below }
-
- with pb, fpb, hpb do begin
- ioNamePtr := @appname; ioFCBIndx := 0;
- if PBGetFCBInfo (@pb, false) <> noErr then ProgramBreak ('NetWork Library: GetFCBInfo failed')
- else begin
- ioVRefNum:= ioFCBVRefNum; { copy volume }
- iodirid:= ioFCBParId; { copy dirid }
- if PBHGetFInfo (@pb, false) = noErr then pFileSignature := longint (ioFlFndrInfo.fdCreator);
- end;
- end;
-
- with gControl do begin
- if OpenDriver ('.Network Processor', ioRefNum) <> noErr then
- gError := notOpenErr { less confusing than resource not found }
- else begin
- longint (ioBuffer) := longint (LibRelease); { library release }
- csCode := csCheckVers;
- gError := PBControl (@gControl, false);
- end;
- end;
-
- if gError = noErr then with gControl do begin
- csCode := csProcKnown; { test if this process is known to NetWork Processor }
- if PBControl (@gControl, false) <> noErr then begin
- ioIndex := pMaster; { default }
- ioSignature := pFileSignature;
- end;
- if ioIndex = pUnknown then ioIndex := pMaster;
- end;
- if gError = noErr then with gControl do begin
- csCode := csMsgInit; gError := PBControl (@gControl, false);
- if gError <> noErr then ioSignature := 0
- else pProcessSignature := ioSignature;
- end;
- if gError = noErr then gError := UseEventNo (eventno);
- InitNetWork := gError;
- if (gError <> noErr) then with gControl do begin
- csCode := csMsgExit; gError := PBControl (@gControl, false); { clean up as much as possible }
- gControl.ioRefNum := 0; { any control call will fail }
- gError := notOpenErr;
- end;
- end;
-
- function ExitNetWork : OSErr;
- begin
- if gControl.ioRefNum = 0 then ExitNetWork := notOpenErr
- else begin
- gControl.csCode := csMsgExit;
- gError := PBControl (@gControl, false);
- ExitNetWork := gError;
- gControl.ioRefnum := 0;
- end;
- end;
-
- end.
-
-
-